package com.aismy.admin.service.impl;

import com.aismy.admin.dto.QuestionDTO;
import com.aismy.admin.dto.QuestionOptionDTO;
import com.aismy.admin.entity.Question;
import com.aismy.admin.entity.QuestionOption;
import com.aismy.admin.entity.EvalScale;
import com.aismy.admin.exception.BusinessException;
import com.aismy.admin.mapper.QuestionMapper;
import com.aismy.admin.service.QuestionService;
import com.aismy.admin.service.QuestionOptionService;
import com.aismy.admin.service.EvalScaleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.micrometer.common.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {

    private final EvalScaleService scaleService;
    private final QuestionOptionService optionService;

    @Override
    public List<Question> getQuestionsByScaleId(Long scaleId) {
        return list(new LambdaQueryWrapper<Question>()
                .eq(Question::getScaleId, scaleId)
                .orderByAsc(Question::getSort));
    }

    @Override
    @Transactional
    public void addQuestion(Long scaleId, Question question) {
        question.setScaleId(scaleId);
        save(question);
    }

    @Override
    @Transactional
    public void updateQuestion(Long scaleId, Question question) {
        question.setScaleId(scaleId);
        updateById(question);
    }

    @Override
    @Transactional
    public void deleteQuestion(Long scaleId, Long questionId) {
        remove(new LambdaQueryWrapper<Question>()
                .eq(Question::getScaleId, scaleId)
                .eq(Question::getId, questionId));
    }

    @Override
    public Page<Question> getQuestionPage(Integer page, Integer size, Integer scaleId, String query) {
        Page<Question> questionPage = this.page(
                new Page<>(page, size),
                new LambdaQueryWrapper<Question>()
                        .eq(scaleId != null, Question::getScaleId, scaleId)
                        .like(StringUtils.isNotBlank(query), Question::getContent, query)
                        .orderByDesc(Question::getCreatedAt)
        );

        // 填充量表信息
        if (questionPage.getRecords() != null && !questionPage.getRecords().isEmpty()) {
            questionPage.getRecords().forEach(question -> {
                EvalScale scale = scaleService.getById(question.getScaleId());
                if (scale != null) {
                    question.setScaleName(scale.getName());
                }
            });
        }

        return questionPage;
    }

    @Override
    public QuestionDTO getQuestionWithOptions(Long id) {
        // 获取题目信息
        Question question = this.getById(id);
        if (question == null) {
            return null;
        }

        // 转换为DTO
        QuestionDTO questionDTO = new QuestionDTO();
        BeanUtils.copyProperties(question, questionDTO);

        // 获取选项信息
        if (!"TEXT".equals(question.getType())) {
            List<QuestionOption> options = optionService.list(
                    new LambdaQueryWrapper<QuestionOption>()
                            .eq(QuestionOption::getQuestionId, id)
                            .orderByAsc(QuestionOption::getSort)
            );

            questionDTO.setOptions(options.stream().map(option -> {
                QuestionOptionDTO optionDTO = new QuestionOptionDTO();
                BeanUtils.copyProperties(option, optionDTO);
                return optionDTO;
            }).collect(Collectors.toList()));
        }

        return questionDTO;
    }

    @Override
    @Transactional
    public void saveQuestionWithOptions(QuestionDTO questionDTO) {
        EvalScale scale = scaleService.getById(questionDTO.getScaleId());
        if (scale == null) {
            throw new BusinessException("关联的量表不存在");
        }
        // 总分
        Integer totalScore = scale.getTotalScore();
        // 当前题目总分
        List<Question> savedQuestions = list(new LambdaQueryWrapper<Question>()
                .eq(Question::getScaleId, questionDTO.getScaleId()));
        int sum = savedQuestions.stream().mapToInt(Question::getScore).sum();
        if (sum + questionDTO.getScore() > totalScore) {
            throw new BusinessException("题目总分超过量表总分");
        }
        // 检测选项分数是否大于题目分数
        for (QuestionOptionDTO optionDTO : questionDTO.getOptions()) {
            if (optionDTO.getScore() > questionDTO.getScore()) {
                throw new BusinessException("选项分数不能大于题目分数");
            }
        }
        // 保存题目
        Question question = new Question();
        BeanUtils.copyProperties(questionDTO, question);
        this.save(question);

        // 保存选项
        if (questionDTO.getOptions() != null && !questionDTO.getOptions().isEmpty()) {
            List<QuestionOption> options = questionDTO.getOptions().stream().map(optionDTO -> {
                QuestionOption option = new QuestionOption();
                BeanUtils.copyProperties(optionDTO, option);
                option.setQuestionId(question.getId());
                return option;
            }).collect(Collectors.toList());

            optionService.saveBatch(options);
        }
    }

    @Override
    @Transactional
    public void updateQuestionWithOptions(QuestionDTO questionDTO) {
        // 更新题目
        Question question = new Question();
        BeanUtils.copyProperties(questionDTO, question);
        this.updateById(question);

        // 删除原有选项
        optionService.remove(
                new LambdaQueryWrapper<QuestionOption>()
                        .eq(QuestionOption::getQuestionId, question.getId())
        );

        // 保存新选项
        if (questionDTO.getOptions() != null && !questionDTO.getOptions().isEmpty()) {
            List<QuestionOption> options = questionDTO.getOptions().stream().map(optionDTO -> {
                QuestionOption option = new QuestionOption();
                BeanUtils.copyProperties(optionDTO, option);
                option.setQuestionId(question.getId());
                return option;
            }).collect(Collectors.toList());

            optionService.saveBatch(options);
        }
    }

    @Override
    @Transactional
    public void removeQuestionWithOptions(Long id) {
        // 删除选项
        optionService.remove(
                new LambdaQueryWrapper<QuestionOption>()
                        .eq(QuestionOption::getQuestionId, id)
        );

        // 删除题目
        this.removeById(id);
    }
} 